今天介紹 watchEffect
與 Lifecycle hooks
const count = ref(0)
watchEffect(() => console.log(count.value)) // log 出 0
setTimeout(() => {
count.value++ // log 出 1, 2, 3...
}, 100)
watchEffect 回傳一個函數 WachStopHandle
,該函數無回傳值,主要是用來讓我們停止 watchEffect。
參考一下這個範例:
// 建立一個 watchEffect
const watcher = watchEffect(() => '')
watcher() // 停止 watchEffect
此外, WatchStopHandle
接受一個參數 onInvalidate
,這是一個 function。在某些場合我們的 watcher 會使用到異步操作,這些操作可能需要在執行後做一些其他任務,例如更改狀態,這時就可以使用到這個 onInvalidate
function,它的觸發時機有兩個實行時機:
範例:
// 這個 watcher 會在 token 變更的時候被觸發
const watcher = watchEffect(async (onInvalidate) => {
state.user = async apis.getUser(token.value)
// 當 token 變更後,會執行 token.forget 將之前的 token 清除
onInvalidate(() => {
token.forget()
})
})
watchEffect 的實行時機是在 Vue 元件的狀態更新後執行。
<template>
<div>{{ count }}</div>
</template>
<script>
export default {
setup() {
const count = ref(0)
watchEffect(() => {
console.log(count.value)
})
return {
count,
}
},
}
</script>
如果你有要同步甚至在狀態更新前執行 effect 的需求,可以透過傳遞第二個參數給 watchEffect
來控制,watchEffect
的第二個參數是一個選擇性物件,這個物件有一個屬性 flush
,用來控制執行時機,預設值是 post
,你可以將它改成 sync
來變成同步,或是 pre
來達成狀態更新前先執行 effect。
export default {
setup() {
watchEffect(() => {
// something here ..
}, { flush: 'sync' }) // 將 effect 改為同步執行
}
}
這裡是所有的 Lifecycle hooks,可透過 import 拿到。
在 Vue3 中並沒有 beforeCreate
與 created
,如果你有想寫在這兩個 hook 裡的東西,請直接寫在 setup
裡面。
setup
會在 mount
之前執行,所以如果你有需要訪問到 DOM,請將程式寫在 onMounted 中。
export default {
setup() {
onMounted(() => {
// do something with DOM ...
})
}
}